package com.dnjn.happiness.emo.assist;

import com.dnjn.happiness.common.core.utils.JsonUtils;
import com.dnjn.happiness.emo.domain.UserRecordFer;
import com.dnjn.happiness.emo.service.IUserRecordFerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 *
 */
@Slf4j
@Component("ferScheduleJob")
public class FerScheduleJob {
    @Autowired
    private IUserRecordFerService ferService;
    @Autowired
    private FerAssist ferAssist;

    public void handleRecordFer(Integer count, Integer batchSize) {
        try {
            StopWatch stopWatch = new StopWatch("fer_emo");
            stopWatch.start("query");
            log.info("start fer_emo job");
            // 3s 一次 重复5次
            List<UserRecordFer> list = getUserRecordFerList(count, batchSize);

            log.info("fer_emo job {}", list.size());
            // 防止重复执行,,
            List<Long> ferIds = list.stream().map(UserRecordFer::getFerId).collect(Collectors.toList());
            if (!list.isEmpty()) {
                ferService.lambdaUpdate().set(UserRecordFer::getFerStatus, 1).in(UserRecordFer::getFerId, ferIds).update();
            }
            stopWatch.stop();
            stopWatch.start("post-fer");
            //get emotionCode
            FerAssist.FerOut out = ferAssist.postFer(list);
            log.info("resp {}", JsonUtils.toJsonString(out));
            stopWatch.stop();
            stopWatch.start("update-record");

            List<UserRecordFer> resultList = iconvUserRecordFerList(out);

            // update ferStatus
            Set<Long> ferIdSet = resultList.stream().map(UserRecordFer::getFerId).collect(Collectors.toSet());
            List<Long> unFerIdList = ferIds.stream().filter(id -> !ferIdSet.contains(id)).collect(Collectors.toList());

            ferService.updateFerCountFailed(unFerIdList);

            // update emotion code
            ferService.updateEmotionCode(resultList);


            stopWatch.stop();
            if (log.isInfoEnabled() && !ferIds.isEmpty()) {
                log.info("fer_emo stopwatch {}s \n{}", stopWatch.getTotalTimeSeconds(), stopWatch.prettyPrint());
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

    }

    @NotNull
    private List<UserRecordFer> iconvUserRecordFerList(FerAssist.FerOut out) {
        return Optional.ofNullable(out.getResult()).
                orElse(new ArrayList<>())
                .stream()
                .map(el -> new UserRecordFer()
                        .setFerId(el.getFerId())
                        .setImageUrl(el.getUrl())
                        .setEmotionCode(el.getEmo()))
                .collect(Collectors.toList())
                ;
    }

    private List<UserRecordFer> getUserRecordFerList(Integer count, Integer batchSize) {
        return ferService.lambdaQuery()
                .le(UserRecordFer::getCreateTime, LocalDateTime.now())
                .le(UserRecordFer::getFerCount, count)
                .eq(UserRecordFer::getFerStatus, 0)
                .select(UserRecordFer::getFerId, UserRecordFer::getImageUrl, UserRecordFer::getFerCount)
                .last(String.format("limit %d", batchSize))
                .list();
    }

}
